﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Opennav.MapGenerator.Geometry;

namespace Opennav.MapGenerator.OSM
{
    public class BinCache
    {
        private BinNodesCache _nodes;
        private BinRelationsCache _relations;
        private BinWaysCache _ways;

        private BinCache()
        {
        }

        public IEnumerable<OSMNode> Nodes { get { return _nodes; } }

        public IEnumerable<OSMRelation> Relations { get { return _relations; } }

        public IEnumerable<OSMWay> Ways { get { return _ways; } }

        public IList<Coordinate> ResolveCoordinates(OSMWay way)
        {
            return _nodes.ResolveCoordinates(way);
        }

        public IList<OSMNode> ResolveNodes(OSMWay way)
        {
            return _nodes.ResolveNodes(way);
        }

        public OSMWay GetWay(uint id)
        {
            return _ways.Get(id);
        }

        public Coordinate GetCoordinate(uint nodeId)
        {
            return _nodes.GetCoordinate(nodeId);
        }

        public OSMNode GetNode(uint nodeId)
        {
            return _nodes.GetNode(nodeId);
        }

        public int CountNodes { get { return _nodes.Count; } }

        public int CountRelations { get { return _relations.Count; } }

        public int CountWays { get { return _ways.Count; } }

        public static BinCache LoadFromXml(string osmXmlFile, string tempFolder)
        {
            BinCache cache = new BinCache();
            cache._nodes = new BinNodesCache(tempFolder, false);
            cache._relations = new BinRelationsCache(tempFolder, false);
            cache._ways = new BinWaysCache(tempFolder, false);
            OSMEntity element;
            OSMSequentialReader rdr = new OSMSequentialReader(osmXmlFile);
            while ((element = rdr.ReadNext()) != null)
            {
                if (element.EntityType == OSMEntityType.Node)
                    cache._nodes.Add((OSMNode)element);
                else if (element.EntityType == OSMEntityType.Way)
                    cache._ways.Add((OSMWay)element);
                else if (element.EntityType == OSMEntityType.Relation)
                    cache._relations.Add((OSMRelation)element);
            }
            return cache;
        }

        public void Close()
        {
            _ways.Close();
            _relations.Close();
            _nodes.Close();
        }
    }
}
